﻿using CubeCube.Sector;
using CubeCube.Tile;
using CubeCube.Utils;
using CubeCube.World;
using CubeCube.World.Generator;
using System.IO;

namespace CubeCube.Chunk
{
    public class Chunk
    {
        public TileManager tileManager;
        public SectorManager sectorManager;
        public CubeWorld world;
        public IndexPosition tileOffset;
        public string terrainName;

        public Chunk(CubeWorld world, IndexPosition tileOffset)
        {
            this.world = world;
            this.tileOffset = tileOffset;
            this.sectorManager = new SectorManager(world, this);
            this.tileManager = new TileManager(world, this);
        }

        public void Create()
        {
            tileManager.Create(world.config.tileDefinitions, Graphics.CHUNK_SIZE, Graphics.CHUNK_SIZE, Graphics.CHUNK_SIZE);
            sectorManager.Create();
        }

        public CubeWorldGenerator Generate(CubeWorldGenerator generator)
        {
            return this.tileManager.Generate(generator);
        }

        //查询tilepos是否在该chunk内
        public bool ContainTilePosition(IndexPosition pos)
        {
            IndexPosition offset = pos - tileOffset;
            if (offset.x > 0 && offset.y > 0 && offset.z > 0 &&
                offset.x < Graphics.CHUNK_SIZE && offset.y < Graphics.CHUNK_SIZE && offset.z < Graphics.CHUNK_SIZE)
            {
                return true;
            }
            return false;
        }


        public void Update(float deltaTime)
        {
            tileManager.Update(deltaTime);
            sectorManager.Update(deltaTime);
        }


        public Chunk GetNearChunck(Graphics.Faces face)
        {
            IndexPosition pos = tileOffset + Graphics.FACE_DIR_VECTOR[(int)face];
            return world.chunkManager.GetChunk(pos);
        }

        public override string ToString()
        {
            return tileOffset.ToString();
        }

        public void Load(BinaryReader br)
        {
            tileManager.Load(br);
            sectorManager.Load(br);
            tileOffset.Evaluate(br.ReadString());
            terrainName = br.ReadString();
        }

        public void Save(BinaryWriter bw)
        {
            tileManager.Save(bw);
            sectorManager.Save(bw);
            bw.Write(tileOffset.ToString());
            bw.Write(terrainName);
        }
    }
}
